package terra.model;

import java.util.Vector;

import org.newdawn.slick.Graphics;
import org.newdawn.slick.geom.Vector2f;

import terra.Config;
import terra.managers.LightManager;
import terra.managers.MapManager;
import terra.managers.ResourceManager;
import terra.slick.GameState;

public class WeatherSystem {

	public static ClientWeather current;
	public static ClientWeather next;
	static long timer;
	public static float lightIntense;
	static Vector<Vector2f> currentVec = new Vector<Vector2f>();
	static Vector<Vector2f> nextVec = new Vector<Vector2f>();
	static float percCurrent;
	
	public static void update(int delta){
		if (timer <= 0){
			if (current != null)
				updateCurrent(delta);
		} else {
			if (current == null || next == null)
				return;
			timer-=delta;
			percCurrent = timer/150/100f;
			lightIntense = current.lightIntense*percCurrent + next.lightIntense*(1f-percCurrent);
			updateCurrent(delta);
			updateNext(delta);
			if (timer <= 0){
				setCurrent(next);
				next = null;
			}
		}
	}

	private static void updateNext(int delta) {
		if (next.def!= null && !next.def.needUpdate)
			return;
		if (next.intensity*(1f-percCurrent)*7 >= 1)
			for(int i = 0; i < next.intensity*(1f-percCurrent)*7;i++)
				nextVec.add(new Vector2f(-150+ GameState.rnd.nextInt(GameState.getInstance().getGc().getWidth()+300),-32));
		for(int i = 0; i < nextVec.size();i++){
			Vector2f v = nextVec.get(i);
			if (next.def.id == 1)
				v.add(new Vector2f(0,2f+ GameState.rnd.nextFloat()*2));
			else if (next.def.id == 2)
				v.add(new Vector2f(0,1f+ GameState.rnd.nextFloat()));
			if (v.getY() > GameState.getInstance().getGc().getHeight()){
				nextVec.remove(i);
				continue;
			}
			MapObject obj = MapManager.getInstance().getTile(
					(int)v.getX()/Config.tileSize+GameState.getInstance().getTiledOffsetX(),
					(int)v.getY()/Config.tileSize+GameState.getInstance().getTiledOffsetY()+1);
			if (obj != null && obj.type == MapObject.TYPE_GROUND)
				nextVec.remove(i);
		}
	}

	private static void updateCurrent(int delta){
		if (current.def!= null && !current.def.needUpdate)
			return;
		if (current.intensity*percCurrent*7 >= 1)
			for(int i = 0; i < current.intensity*percCurrent*7;i++)
				currentVec.add(new Vector2f(-150+ GameState.rnd.nextInt(GameState.getInstance().getGc().getWidth()+300),-32));
		
		for(int i = 0; i < currentVec.size();i++){
			Vector2f v = currentVec.get(i);
			if (current.def.id == 1)
				v.add(new Vector2f(0,2f+ GameState.rnd.nextFloat()*2));
			else if (current.def.id == 2)
				v.add(new Vector2f(0,1f+ GameState.rnd.nextFloat()));
			if (v.getY() > GameState.getInstance().getGc().getHeight()){
				currentVec.remove(i);
				continue;
			}
			MapObject obj = MapManager.getInstance().getTile(
					(int)v.getX()/Config.tileSize+GameState.getInstance().getTiledOffsetX(),
					(int)v.getY()/Config.tileSize+GameState.getInstance().getTiledOffsetY()+1);
			if (obj != null && obj.type == MapObject.TYPE_GROUND)
				currentVec.remove(i);
		}
	}
	
	public static void draw(Graphics g){
		if (timer <= 0){
			if (current != null)
				drawCurrent(g);
		} else {
			if (current != null)
				drawCurrent(g);
			if (next != null)
				drawNext(g);
		}
	}
	
	private static void drawNext(Graphics g) {
		if (!next.def.needUpdate)
			return;
		g.setColor(GameState.waterColor);
		for(int i = 0; i < nextVec.size();i++){
			Vector2f v = nextVec.get(i);
			if (next.def.id == 1) {
				g.drawLine(v.getX()+GameState.getInstance().getOffsetX(), v.getY()+GameState.getInstance().getOffsetY(),
						v.getX()+GameState.getInstance().getOffsetX(), v.getY()+GameState.getInstance().getOffsetY()+8);
			} else if (next.def.id == 2) {
				LightManager.getInstance().blend((int)v.getX()/Config.tileSize+4, (int)v.getY()/Config.tileSize+4, ResourceManager.getImage("snowflake"));
				g.drawImage(ResourceManager.getImage("snowflake"),
						v.getX()+GameState.getInstance().getOffsetX(), v.getY()+GameState.getInstance().getOffsetY());
			}
		}
	}

	private static void drawCurrent(Graphics g) {
		if (!current.def.needUpdate)
			return;
		g.setColor(GameState.waterColor);
		for(int i = 0; i < currentVec.size();i++){
			Vector2f v = currentVec.get(i);
			if (current.def.id == 1){
				g.drawLine(v.getX()+GameState.getInstance().getOffsetX(), v.getY()+GameState.getInstance().getOffsetY(),
						v.getX()+GameState.getInstance().getOffsetX(), v.getY()+GameState.getInstance().getOffsetY()+8);
			} else if (current.def.id == 2){
				LightManager.getInstance().blend((int)v.getX()/Config.tileSize+4, (int)v.getY()/Config.tileSize+4, ResourceManager.getImage("snowflake"));
				g.drawImage(ResourceManager.getImage("snowflake"),
						v.getX()+GameState.getInstance().getOffsetX(), v.getY()+GameState.getInstance().getOffsetY());
			}
		}
	}

	public static void setCurrent(Weather w){
		current = (ClientWeather) w;
		lightIntense = current.lightIntense;
		percCurrent = 1f;
		currentVec.clear();
		currentVec.addAll(nextVec);
		timer = 0;
	}
	
	public static void setNext(Weather w){
		next = (ClientWeather) w;
		nextVec.clear();
		timer = 15000;
	}
	
}
